import re
import os
import csv
import requests
import sqlite3
from bs4 import BeautifulSoup
from request_utils import ask_url
from save_to_csv_utils import save_csv

# 爬取的地址以及保存的文件名
BASE_URL = "https://movie.douban.com/top250?start="
CSV_PATH = "../影片Top.csv"
DB_PATH = "../影片Top.db"

# 通过正则表达式提取前端的数据
# 影片详情链接
FIND_LIST = re.compile(r'<a href="(.*?)">')  # 创建正则表达式对象，表示规则（字符串的模式）
# 影片图片
FIND_IMG = re.compile(r'<img.*src="(.*?)"', re.S)  # re.S让换行包含在字符中
# 影片片名
FIND_TITLE = re.compile(r'<span class="title">(.*)</span>')
# 影片评分
FIND_RATING = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
# 评价人数
FIND_JUDGE_PEOPLE = re.compile(r'<span>(\d*)人评价</span>')
# 找到概况
FIND_SUM = re.compile(r'<span>(.*)</span>')
# 找到影片的相关内容
FIND_BG = re.compile(r'<p>(.*?)</p>', re.S)


def main():
    """主函数：协调数据爬取、解析和存储流程"""
    # 1.爬取数据
    movie_data = get_movie_data(BASE_URL)

    # 2.保存数据
    save_to_csv(movie_data, CSV_PATH)
    save_to_database(movie_data, DB_PATH)


# 爬取网页
def get_movie_data(base_url):
    """爬取豆瓣电影Top的数据"""
    datalist = []

    # 分页爬取
    for page in range(10):
        url = base_url + str(page * 25)
        html_content = ask_url(url)

        # 注意解析数据，根据前面正则表达式提取数据
        # 后面是解析器
        soup = BeautifulSoup(html_content, 'html.parser')
        movie_items = soup.find_all('div', class_='item')

        # 查找符合要求的字符串，形成列表
        for item in movie_items:
            # 存储一部电影的所有信息
            data = []
            item = str(item)

            # 获取影片详情的链接
            link = re.findall(FIND_LIST, item)[0]
            data.append(link)

            # 获取影片图片信息
            img_src = re.findall(FIND_IMG, item)[0]
            data.append(img_src)

            # 获取影片片名
            title = re.findall(FIND_TITLE, item)
            if len(title) == 2:
                # 添加中文名
                c_title = title[0]
                data.append(c_title)

                # 添加外国名
                f_title = title[1].replace("/", "")
                data.append(f_title)
            else:
                # 若无外国名，则留空
                data.append(title[0])
                data.append(' ')

            # 获取影片评分
            rating = re.findall(FIND_RATING, item)[0]
            data.append(rating)

            # 获取影片评价人数
            judge_num = re.findall(FIND_JUDGE_PEOPLE, item)[0]
            data.append(judge_num)

            # 获取影片概述
            inq = re.findall(FIND_SUM, item)
            if len(inq) > 1:
                inq = inq[1].replace("。", "")
                data.append(inq)
            else:
                data.append(" ")

            bd = re.findall(FIND_BG, item)[0]
            bd = re.sub("/", '', bd)  # 去掉/
            bd = re.sub(' ', '', bd)  # 去掉空格
            bd = re.sub('\n', '', bd)  # \n
            data.append(bd)  # 将处理好的数据添加

            # 把处理好的信息放入datalist中
            datalist.append(data)

    return datalist


def save_to_csv(datalist, csv_path):
    """使用csv模块保存数据"""
    headers = ('电影详情链接', '电影图片链接', '影片中文名',
               '影片外国名', '评分', '评价数量', '概况', '详情信息')

    save_csv(datalist, csv_path, headers)


def save_to_database(datalist, db_path):
    """将数据保存到SQLite数据库"""
    # 若存在文件，那么覆盖
    if os.path.exists(db_path):
        os.remove(db_path)

    # 初始化数据库
    init_db(db_path)

    try:
        conn = sqlite3.connect(db_path)
        cursor = conn.cursor()

        i = 1
        for data in datalist:
            print(f"正在写入第 {i} 条db数据")
            i = i + 1

            for index in range(len(data)):
                if index == 4 or index == 5:
                    continue
                data[index] = '"' + data[index] + '"'

            sql = '''
                insert into movie (
                info_link, pic_url, cname, ename, score, rated, introduction, info)
                values(%s)''' % ",".join(data)
            # print(sql)

            cursor.execute(sql)
            conn.commit()

        cursor.close()
        conn.close()
        print(f"数据已成功保存到 {db_path}")
    except Exception as e:
        print(f"保存到数据库时出错: {e}")


def init_db(db_path):
    """初始化SQLite数据库结构"""
    sql = '''
        create table movie (
            info_link text,
            pic_url text,
            cname varchar,
            ename varchar,
            score numeric,
            rated numeric,
            introduction text,
            info text
        )
    '''

    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    cursor.execute(sql)
    conn.commit()
    conn.close()


if __name__ == '__main__':
    main()
    print("影片TOP爬取完毕")